package myalg.diningphilosophers2;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @author Pavel Belevich
 *         Date: Jun 26, 2012
 *         Time: 1:45:37 PM
 */
public class Main {

    private List<Philosopher> philosophers = new ArrayList<Philosopher>();
    private List<Fork> forks = new ArrayList<Fork>();

    public void run(int philosophersCount) throws InterruptedException {

        BlockingQueue<Philosopher> q = new LinkedBlockingQueue<Philosopher>();
        CountDownLatch c = new CountDownLatch(philosophersCount);

        Fork left = null;
        for (int i = 0 ; i < philosophersCount ; i++) {
            Philosopher philosopher = new Philosopher(String.valueOf(i+1), q, c);
            Fork right = new SynchronizedFork();
            forks.add(right);
            philosopher.setLeft(left);
            philosopher.setRight(right);
            left = right;
            philosophers.add(philosopher);
            new Thread(philosopher, philosopher.getName()).start();
        }
        philosophers.get(0).setLeft(left);
        while (true) {
            Philosopher p = q.take();
            synchronized (p) {
                if (!p.isReady()) {
                    p.wait();
                }
            }
            StringBuilder s = new StringBuilder();
            for (Philosopher philosopher : philosophers) {
                s.append(philosopher.getState());
            }
            s.append("\t");
            for (Fork f : forks) {
                s.append(f.getHolder() == null ? 0 : f.getHolder().getName());
            }
            System.out.println(s.toString());
            synchronized (p) {
                p.setReady(false);
                p.notify();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new Main().run(10);
    }

}
